﻿#include "widget.h"
#include "./ui_widget.h"
#include <QMessageBox>
#include <QFileDialog>
#include <QStandardPaths>
#include <QDoubleSpinBox>
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    scene_srcImg = new QGraphicsScene(this);    // 显示原图
    scene_grayImg = new QGraphicsScene(this);   // 显示灰度图
    scene_dstImg = new QGraphicsScene(this);    // 显示处理结果

    srcImgPath = "";                            // 原图路径
    ehceProc = new CImgEnhance;                 // 图像增强功能

    ui->stackedWidget_enhc->hide();

    // 图像处理功能默认隐藏
    ui->stackedWidget_ppc->hide();

    // 伽马变换的参数范围设定
    ui->douSpinBox_enhC->setMinimum(0.01);
    ui->douSpinBox_enhG->setMinimum(0.01);
    ui->douSpinBox_enhC->setValue(1.00);
    ui->douSpinBox_enhG->setValue(1.00);
    ui->douSpinBox_enhC->setSingleStep(0.1);
    ui->douSpinBox_enhG->setSingleStep(0.1);

    // 对数变换的参数范围设定
    ui->doubleBox_enhLog->setMinimum(0.01);
    ui->doubleBox_enhLog->setSingleStep(0.1);
    ui->doubleBox_enhLog->setValue(1.00);

    // 初始化图像增强
    connect(ui->comboBox_enhance,&MyComBox::sgl_addWays,this,[=](){
        ui->stackedWidget_enhc->hide();
        ui->comboBox_enhance->clear();
        QStringList itemList;
        itemList<<"伽马变换"<<"对数变换"<<"反变换"<<"直方图均衡化";
        ui->comboBox_enhance->addItems(itemList);
        ui->comboBox_enhance->setCurrentIndex(-1); // 初始不显示任何选项
    });
//    // 显式连接信号槽
//    connect(ui->doubleBox_enhLog, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
//            this, &Widget::on_doubleBox_enhLog_valueChanged);


}

Widget::~Widget()
{
    delete ui;
    delete ehceProc;
}

/**
 * @brief Mat -> QPixMap 显示到QGraphicsView的QGraphicsScene
 * @param mat
 * @param view
 * @param scene
 */
void Widget::showMatInGraphicsView(cv::Mat& mat, QGraphicsView* view, QGraphicsScene* scene) {
    if (mat.empty()) {
        qDebug() << "Error: Input image is empty!";
        return;
    }
    // 转换颜色空间
    cv::Mat displayMat;
    if (mat.channels() == 3) {
        cv::cvtColor(mat, displayMat, cv::COLOR_BGR2RGB);
    } else if (mat.channels() == 1) {
        cv::cvtColor(mat, displayMat, cv::COLOR_GRAY2RGB);
    } else {
        qDebug() << "Unsupported image format!";
        return;
    }
    // 确保内存连续
    if (!displayMat.isContinuous()) {
        displayMat = displayMat.clone();
    }
    // 创建QImage和QPixmap
    QImage qimg(displayMat.data, displayMat.cols, displayMat.rows,displayMat.step, QImage::Format_RGB888);
    QPixmap pixmap = QPixmap::fromImage(qimg);
    // 清空场景并添加图像
    scene->clear();
    scene->addPixmap(pixmap);
    view->setScene(scene);
    // 关键修改：居中显示且不缩放                            // View 是“摄像头”，Scene 是“舞台”，图像通过 Scene 添加到 View 中显示
    view->resetTransform(); // 重置任何变换（缩放/旋转）
    view->setSceneRect(QRectF(0, 0, pixmap.width(), pixmap.height())); // 设置场景大小=图像大小
    view->centerOn(scene->itemsBoundingRect().center()); // 居中显示
    view->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); // 按需显示滚动条
    view->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
}

/**
 * @brief 读取原图
 */
void Widget::on_btnReadOrgImg_clicked()
{
    QString path = ui->lineEdit_orgImgPath->text();
    if(path.isEmpty()){
        QMessageBox::information(this,"提示","未选择图片");
        return;
    }
//    if(srcImgPath == path){
//        QMessageBox::information(this,"提示","当前路径的图片已经导入");
//        return;
//    }
    scene_srcImg->clear();                              // 清空当前显示
    scene_grayImg->clear();
    scene_dstImg->clear();
    ui->grapView_srcImg->setScene(scene_srcImg);
    ui->grapView_grayImg->setScene(scene_grayImg);
    ui->grapView_dstImg->setScene(scene_dstImg);

    srcImgPath = path;                                  // 读取图像
    mSrcImg = cv::imread(srcImgPath.toStdString());
    if(mSrcImg.empty()){
        QMessageBox::critical(this,"错误","图像读取错误，请检查路径是否正确");
        return;
    }
    mGrayImg = cv::imread(srcImgPath.toStdString(),0);
    showMatInGraphicsView(mSrcImg,ui->grapView_srcImg,scene_srcImg);
    showMatInGraphicsView(mGrayImg,ui->grapView_grayImg,scene_grayImg);
    ui->stackedWidget->setCurrentIndex(0);                              // 显示导入的图像

}

/**
 * @brief 选择图片，获取图片路径
 */
void Widget::on_toolBtnGetPath_clicked()
{
    QString imgType = "Image(*.png *.jpg)";

    // 获取系统桌面路径
    QString desktopPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
    // 设置默认从桌面打开
    QString path = QFileDialog::getOpenFileName(
        this,
        "选择图片",
        desktopPath,
        imgType
    );

    ui->lineEdit_orgImgPath->setText(path);
}

/**
 * @brief 图像显示：显示原图
 */
void Widget::on_btnShowSrc_clicked()
{
    ui->stackedWidget->setCurrentIndex(0);
}

/**
 * @brief 图像显示：显示灰度图
 */
void Widget::on_btnShowGray_clicked()
{
    ui->stackedWidget->setCurrentIndex(2);
}

/**
 * @brief 图像显示：显示处理结果
 */
void Widget::on_btnShowDst_clicked()
{
    ui->stackedWidget->setCurrentIndex(1);
}

/**
 * @brief 图像处理方式：图像增强
 */
void Widget::on_btnEnhance_clicked()
{
    ui->stackedWidget_ppc->show();
    ui->stackedWidget_ppc->setCurrentIndex(0);
}

/**
 * @brief 图像处理方式：空间滤波
 */
void Widget::on_btnSpacFilt_clicked()
{
    ui->stackedWidget_ppc->show();
    ui->stackedWidget_ppc->setCurrentIndex(1);
}

/**
 * @brief UI中调用幂变换，增强图像
 */
void Widget::uiEnhcPowerTransform()
{
    float fc = (float)ui->douSpinBox_enhC->value();
    float fg = (float)ui->douSpinBox_enhG->value();
    // 幂变换
    mDstImg = mGrayImg.clone(); // 深拷贝，不影响原图
    ehceProc->power_transform(mGrayImg,mDstImg,fc,fg);
//    ehceProc->power_tansformSIMD(mGrayImg,mDstImg,fc,fg);
    showMatInGraphicsView(mDstImg,ui->grapView_dstImg,scene_dstImg);
}

/**
 * @brief UI中调用反变换，增强图像
 */
void Widget::uiEnhcRevseTransform()
{
    // 反变换
    mDstImg = mGrayImg.clone();
    ehceProc->reverse_transform(mGrayImg,mDstImg);
    showMatInGraphicsView(mDstImg,ui->grapView_dstImg,scene_dstImg);
}

/**
 * @brief UI中调用直方图均衡化，增强图像
 */
void Widget::uiEnhcHistEqualization()
{
    mDstImg = mGrayImg.clone();
    ehceProc->HistEqualization(mGrayImg,mDstImg);
    showMatInGraphicsView(mDstImg,ui->grapView_dstImg,scene_dstImg);
}

/**
 * @brief UI中调用对数变换，增强图像
 */
void Widget::uiEnhcLogTransform()
{
    float fc = (float)ui->doubleBox_enhLog->value();
    mDstImg = mGrayImg.clone();
    ehceProc->log_transform(mGrayImg,mDstImg,fc);
    showMatInGraphicsView(mDstImg,ui->grapView_dstImg,scene_dstImg);
}

/**
 * @brief 根据 图像增强的 comboBox 的索引，选择功能，对图像进行处理
 * @param index
 */
void Widget::on_comboBox_enhance_activated(int index)
{
    // 幂变换
    if(index==0){
        ui->stackedWidget_enhc->show();
        ui->stackedWidget_enhc->setCurrentIndex(index);
        ui->douSpinBox_enhC->setValue(1.00);
        ui->douSpinBox_enhG->setValue(1.00);
        uiEnhcPowerTransform();
    }
    // 对数变换
    if(index==1){
        ui->stackedWidget_enhc->show();
        ui->stackedWidget_enhc->setCurrentIndex(index);
        ui->doubleBox_enhLog->setValue(1.00);
        uiEnhcLogTransform();
    }
    // 反变换
    if(index==2){
        ui->stackedWidget_enhc->show();
        ui->stackedWidget_enhc->setCurrentIndex(index);
        uiEnhcRevseTransform();
    }
    // 直方图均衡化
    if(index==3){
        uiEnhcHistEqualization();
    }
}
/**
 * @brief 调节参数C，显示幂变换处理的图像
 * @param arg1
 */
void Widget::on_douSpinBox_enhC_valueChanged(double arg1)
{
    if(ui->comboBox_enhance->currentIndex()==0){
        uiEnhcPowerTransform();
    }
}
/**
 * @brief 调节参数G，显示幂变换处理的图像
 * @param arg1
 */
void Widget::on_douSpinBox_enhG_valueChanged(double arg1)
{
    if(ui->comboBox_enhance->currentIndex()==0){
        uiEnhcPowerTransform();
    }
}

/**
 * @brief 调节参数C，显示对数变换处理的图像
 * @param arg1
 */
void Widget::on_doubleBox_enhLog_valueChanged(double arg1)
{
    if(ui->comboBox_enhance->currentIndex()==1){
        uiEnhcLogTransform();
    }
}
